from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.views import View


"""
图形验证码功能：
    前端：拼接一个URL，交给img标签，然后发起请求
         url = http://ip:port/image_codes/uuid/
    后端：
        请求：接受路由中的uuid
        业务逻辑：生成图片验证码和二进制图片，通过redis把图片验证码保存起来     
        响应：返回二进制图片
        
        路由：get image_codes/uuid/
"""
class ImageCodeView(View):

    def get(self, request, uuid):
        # 1.接受路由中的uuid
        # print(uuid)
        # 2.生成图片验证码和图片二进制
        from libs.captcha.captcha import captcha
        # text 是图片验证码的内容，如： xyzz
        # image 是图片二进制
        text, image = captcha.generate_captcha()

        # 3.通过redis把图片验证码数据保存起来
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')  # 链接Redis数据库
        redis_cli.setex(uuid, 180, text)  # 操作Redis数据保存图片验证码数据，并设置过期时间，单位秒

        # 4.返回二进制图片
        # 注：因为图片是二进制，不能使用Jsonreponse返回Json数据
        # content_type=响应体数据类型，语法：大类型/小类型，如 image/jpeg，image/gif，image/png
        # content_type (MIME类型)
        return HttpResponse(image, content_type='image/jpeg')

"""
手机验证码功能：
前端：当用户输入完手机号，验证码，会发送一个axios请求
     url = http://ip:port/sms_codes/mobile/?image_code=value&image_code_id=uuidvalue/
后端：
    请求：接受请求，获取路由参数(手机号)和查询字符串参数(图片验证码，UUID)
    业务逻辑：
        获取请求参数
        验证参数
        生成短信验证码
        保存短信验证码
        发送短信验证码
    响应：返回响应
    
    路由：get sms_codes/mobile/?image_code=value&image_code_id=uuidvalue/
"""
class SmsCodeView(View):
    def get(self, request, mobile):
        # 1.获取请求参数
        image_code = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')

        # 2.验证参数
        if not all([image_code, uuid]):
            return JsonResponse({"code":400, 'errmsg':"参数不全"})

        # 3.验证码图形验证码
        from django_redis import get_redis_connection
        redis_cli =get_redis_connection('code')  # 链接redis数据库
        redis_image_code = redis_cli.get(uuid)  # 根据uuid参数从数据库中获取图片验证码内容
        # redis_images_code 获取到的事bytes类型数据

        if redis_image_code is None:  # redis中存储的图片验证码过期
            return JsonResponse({"code": 400, 'errmsg': "图片验证码已过期"})

        if image_code.lower() != redis_image_code.decode().lower():  # 验证码参数内容与数据库存储内容不一致
            return JsonResponse({"code": 400, 'errmsg': "图片验证码错误"})

        # 提取发送短信的标记，看看是否存在
        send_flag = redis_cli.get("send_flag_%s" %mobile)
        if send_flag is not None:
            return JsonResponse({"code": 400, 'errmsg': "不要频繁发送短信"})

        # 4.生成短信验证码
        from random import randint
        sms_code = randint(100000, 999999)

        # 5.保存短信验证码
        # redis_cli.setex(mobile, 300, sms_code)  # 操作Redis数据保存手机验证码内容，并设置过期时间，单位秒
        # 添加发送短信的标记，有效期60秒，内容随意
        # redis_cli.setex('send_flag_%s' %mobile, 60, 1)

        # 使用pipeline管道提升性能
        # 一、新建一个管道
        pipeline = redis_cli.pipeline()
        # 二、管道收集指令
        pipeline.setex(mobile, 300, sms_code)  # 操作Redis数据保存手机验证码内容，并设置过期时间，单位秒
        pipeline.setex('send_flag_%s' %mobile, 60, 1)  # 加发送短信的标记，有效期60秒，内容随意
        # 三、管道执行收集指令
        pipeline.execute()

        # 6.发送短信验证码
        # from libs.yuntongxun.sms import CCP
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)

        # 使用Celery异步任务发送短信验证码
        from celery_tasks.sms.tasks import celery_send_sms_code
        # 调用delay即添加任务到中间人队列中
        # delay的参数 等同于 生产者任务(函数)的参数
        celery_send_sms_code.delay(mobile, sms_code)

        # 7.返回响应
        return JsonResponse({"code": 0, 'errmsg': "ok"})